#include "miniclient.h"


#include <string.h>
#include <stdint.h>
#include <stdio.h>
int rc;

void 
client_create_blob(struct rpc* mrpc, uint32_t sess_id, rpc_request_func cb, void* cb_arg)
{
    struct msg_base* req_h = alloc_msg_header(mrpc);

    prepare_msg_header(mrpc, req_h, S_CHUNK_IO_SERVICE, 0, 0, 0, 0);
    struct dss_msg* dss_req = (struct dss_msg*)req_h->data;
    dss_req->msg_type = CHUNK_OP_CREATE;
    dss_req->data_len = 0;
    req_h->data_len = sizeof(struct dss_msg);
    enqueue_request(mrpc, sess_id, req_h, cb, cb_arg,0);
}


void 
client_delete_blob(struct rpc* mrpc,uint32_t client_id, uint64_t blob_id, rpc_request_func cb, void* cb_arg)
{
    struct msg_base* req_h = alloc_msg_header(mrpc);

    prepare_msg_header(mrpc, req_h, S_CHUNK_IO_SERVICE, 0, 0, 0, 0);
    struct dss_msg* dss_req = (struct dss_msg*)req_h->data;
    dss_req->msg_type = CHUNK_OP_DELETE;
    struct chunk_req* ck_req = (struct chunk_req*)dss_req->data;
    ck_req->id.cs_id = 0;
    ck_req->id.blob_id = blob_id;
    ck_req->data_len = 0;
    dss_req->data_len = sizeof(struct chunk_req) + ck_req->data_len;

    req_h->data_len = sizeof(struct dss_msg) + dss_req->data_len;
    enqueue_request(mrpc, client_id, req_h, cb, cb_arg, 0);
}

void 
client_write_blob(struct rpc* mrpc, uint32_t client_id, uint64_t blob_id, void* buffer, uint32_t off, uint32_t len, rpc_request_func cb, void* cb_arg)
{
    
    if(len < 1048576)
    {
        struct msg_base* req_h = alloc_msg_header(mrpc);
        prepare_msg_header(mrpc, req_h, S_CHUNK_IO_SERVICE, 0, 0, 0, 0);
        struct dss_msg* dss_req = (struct dss_msg*)req_h->data;
        dss_req->msg_type = CHUNK_OP_WRITE;
        struct chunk_req* ck_req = (struct chunk_req*)dss_req->data;
        ck_req->id.cs_id = 0;
        ck_req->id.blob_id = blob_id;
        ck_req->data_len = len;
        memcpy((void*)ck_req->data, buffer, len);
        ck_req->chunk_len = len;
        ck_req->chunk_off = off;

        dss_req->data_len = sizeof(struct chunk_req) + ck_req->data_len;
        req_h->data_len = sizeof(struct dss_msg) + dss_req->data_len;
        //printf("blobid = %lu, len =%d, data_len =%d", ck_req->id.blob_id, len, req_h->data_len);
        enqueue_request(mrpc, client_id, req_h, cb, cb_arg, 0);
    }
    else
    {
        struct msg_base* req_h = alloc_large(mrpc);
        prepare_msg_header(mrpc, req_h, S_CHUNK_IO_SERVICE, 0, 0, 0, 0);
        struct dss_msg* dss_req = (struct dss_msg*)req_h->data;
        dss_req->msg_type = CHUNK_OP_WRITE;
        struct chunk_req* ck_req = (struct chunk_req*)dss_req->data;
        ck_req->id.cs_id = 0;
        ck_req->id.blob_id = blob_id;
        ck_req->data_len = len;
        memcpy((void*)ck_req->data, buffer, len);
        ck_req->chunk_len = len;
        ck_req->chunk_off = off;

        dss_req->data_len = sizeof(struct chunk_req) + ck_req->data_len;
        req_h->data_len = sizeof(struct dss_msg) + dss_req->data_len;
        //printf("blobid = %lu, len =%d, data_len =%d", ck_req->id.blob_id, len, req_h->data_len);
        enqueue_request(mrpc, client_id, req_h, cb, cb_arg, 0);
    }
}

void 
client_read_blob(struct rpc* mrpc, uint32_t client_id, uint64_t blob_id, void* buffer, uint32_t off, uint32_t len, rpc_request_func cb, void* cb_arg)
{
    struct msg_base* req_h = alloc_msg_header(mrpc);

    prepare_msg_header(mrpc, req_h, S_CHUNK_IO_SERVICE, 0, 0, 0, 0);
    struct dss_msg* dss_req = (struct dss_msg*)req_h->data;
    dss_req->msg_type = CHUNK_OP_READ;
    struct chunk_req* ck_req = (struct chunk_req*)dss_req->data;
    ck_req->id.cs_id = 0;
    ck_req->id.blob_id = blob_id;
    ck_req->data_len = 0;

    ck_req->chunk_len = len;
    ck_req->chunk_off = off;

    dss_req->data_len = sizeof(struct chunk_req) + ck_req->data_len;
    req_h->data_len = sizeof(struct dss_msg) + dss_req->data_len;
    if(len >= 1048576) alloc_remote_large_buf(req_h);
    enqueue_request(mrpc, client_id, req_h, cb, cb_arg, 0);
}


